<?php
/**
 * Note:  APP 公共参数 / 签名校验
 * Date: 2020/6/9
 */
namespace App\Traits;

// use App\Caches\AppCache;
use App\Caches\Game\AppSourceCache;
use App\Caches\Game\UuidWhiteListCache;
use App\Caches\QuickSetCache;
use App\Exceptions\ApiException;
use App\Exceptions\ApiHttpOkException;
use App\Services\AccountOperateLogService;
use App\Services\IpAddrService;
use App\Services\NoticeDingDingService;

// use App\Models\Game\Center\AppResource;
// use Illuminate\Support\Str;

trait AppTrait
{
    /**
     *  APP 公共参数 / 签名校验
     * @throws \Exception
     */
    /*protected function checkApp()
    {
        $data = request()->all();
        // 公共参数 校验
        $validator = validator($data, [
            'appid' => 'required|numeric',
            'ts' => 'required|numeric',
            'sign' => 'required|alpha_dash'
        ]);
        if ($validator->fails()) throw new \Exception($validator->errors()->first());

        $app = AppCache::get(request()->appid);
        if (!$app) throw new \Exception(__('api.app_not_found'));

        if (!$this->verifySign($data, $app->key)) throw new \Exception(__('api.app_verify_failed'));
    }*/

    /**
     * 校验签名
     * @param $data
     * @param $secret
     * @return bool
     */
    protected function verifySign($data, $secret)
    {
        return $data['sign'] === $this->makeSign($data, $secret);
    }

    /**
     * 生成签名
     * @param $data
     * @param $secret
     * @return string
     */
    protected function makeSign($data, $secret)
    {
        if (isset($data['sign'])) unset($data['sign']);
        ksort($data);
        $signString = '';
        foreach ($data as $k => $v) {
            if (empty($v)) continue;
            $signString .= "{$k}={$v}&";
        }
        $signString .= $secret;
        return strtolower(md5($signString));
    }

    /**
     * 检查是否关闭登录
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|void
     * @throws ApiException
     */
    protected function checkCloseLogin()
    {
        $closeLogin = QuickSetCache::get(QuickSetCache::KEY_CLOSE_LOGIN, false);
        if ($closeLogin) {
            if (UuidWhiteListCache::get(request('uuid'))) return;
            throw new ApiException(__('api.shutdown'));
        }

        // 是否开启登录限制
        if (config('game.login_ip_addr_limit') && IpAddrService::isWarning(getClientIp(), IpAddrService::ACTION_LOGIN)) {
            NoticeDingDingService::sendTextOperate('IP登录被ban:'. getClientIp());
            throw new ApiException(__('api.close_register').'(1)');
        }
    }

    /**
     * 检查是否关闭了热更新
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|void
     * @throws ApiException
     */
    protected function checkCloseHotUpdate()
    {
        $closeHotUpdate = QuickSetCache::get(QuickSetCache::KEY_CLOSE_HOT_UPDATE, false);
        if ($closeHotUpdate) {
            // 传递了uuid且在白名单中绕过限制
            if (request('uuid') && UuidWhiteListCache::get(request('uuid'))) return;

            throw new ApiException('热更新已关闭');
        }
    }

    /**
     * 检查是否关闭了强更
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|void
     * @throws ApiException
     */
    protected function checkCloseUpgrade()
    {
        $closeUpgrade = QuickSetCache::get(QuickSetCache::KEY_CLOSE_UPGRADE, false);
        if ($closeUpgrade) {
            // 传递了uuid且在白名单中绕过限制
            if (request('uuid') && UuidWhiteListCache::get(request('uuid'))) return;

            throw new ApiHttpOkException('强更已关闭', [], 0);
        }
    }

    /**
     * 检查是否关闭登录
     * @param int $source
     * @throws ApiException
     */
    protected function checkCloseRegister(int $source)
    {
        $appSource = AppSourceCache::get($source);
        if (!$appSource || !$appSource->register) throw new ApiException(__('api.close_register'));

        // 是否开启登录限制
        // if (config('game.login_ip_addr_limit') && IpAddrService::isWarning(getClientIp(), IpAddrService::ACTION_REG)) {
        //     NoticeDingDingService::sendTextNotice('IP注册被ban:'. getClientIp());
        //     throw new ApiException(__('api.close_register').'(2)');
        // }
    }

    /**
     * 检查是否关闭实名校验
     * @return bool
     */
    protected function checkCloseRealName(): bool
    {
        return (bool) QuickSetCache::get(QuickSetCache::KEY_CLOSE_REAL_NAME, false);
    }

    protected ?AccountOperateLogService $accountOperateLogService = null;

    /**
     * 账户操作服务
     * @return AccountOperateLogService
     */
    protected function getAccountOperateLogService(): AccountOperateLogService
    {
        if (!$this->accountOperateLogService) {
            $this->accountOperateLogService = new AccountOperateLogService();
        }
        return $this->accountOperateLogService;
    }
}
